Coverage Report

Created: 2024-12-19 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
D:\a\tools.proto\tools.proto\compiler\src\gen\template\hook.rs
Line
Count
Source
1
// Copyright (c) 2024, BlockProject 3D
2
//
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without modification,
6
// are permitted provided that the following conditions are met:
7
//
8
//     * Redistributions of source code must retain the above copyright notice,
9
//       this list of conditions and the following disclaimer.
10
//     * Redistributions in binary form must reproduce the above copyright notice,
11
//       this list of conditions and the following disclaimer in the documentation
12
//       and/or other materials provided with the distribution.
13
//     * Neither the name of BlockProject 3D nor the names of its contributors
14
//       may be used to endorse or promote products derived from this software
15
//       without specific prior written permission.
16
//
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
use crate::gen::template::{Error, Scope, Template};
30
use std::collections::HashMap;
31
32
pub trait Render {
33
    fn render_frag(&self, fragment: &Fragment) -> Result<String, Error>;
34
}
35
36
pub trait RenderToVar<'a>: Render {
37
    fn render_frag_to_var(&mut self, fragment: &Fragment, key: &'a str) -> Result<&mut Self, Error>;
38
}
39
40
impl Render for Template<'_, '_> {
41
22
    fn render_frag(&self, fragment: &Fragment) -> Result<String, Error> {
42
22
        self.render(fragment.path, fragment.fragments)
43
22
    }
44
}
45
46
impl Render for Scope<'_, '_, '_> {
47
0
    fn render_frag(&self, fragment: &Fragment) -> Result<String, Error> {
48
0
        self.render(fragment.path, fragment.fragments)
49
0
    }
50
}
51
52
impl<'variable> RenderToVar<'variable> for Scope<'_, '_, 'variable> {
53
0
    fn render_frag_to_var(&mut self, fragment: &Fragment, key: &'variable str) -> Result<&mut Self, Error> {
54
0
        self.render_to_var(fragment.path, fragment.fragments, key)
55
0
    }
56
}
57
58
pub struct Fragment<'b> {
59
    path: &'b str,
60
    fragments: &'b [&'b str],
61
}
62
63
impl<'b> Fragment<'b> {
64
22
    pub fn new(path: &'b str, fragments: &'b [&'b str]) -> Self {
65
22
        Self { path, fragments }
66
22
    }
67
}
68
69
pub enum Hook<'a> {
70
    Fragment(Fragment<'a>),
71
    Function(&'a str),
72
}
73
74
impl<'a> From<&'a str> for Hook<'a> {
75
7
    fn from(value: &'a str) -> Self {
76
7
        Self::Function(value)
77
7
    }
78
}
79
80
impl<'a> From<Fragment<'a>> for Hook<'a> {
81
22
    fn from(value: Fragment<'a>) -> Self {
82
22
        Self::Fragment(value)
83
22
    }
84
}
85
86
pub struct TemplateHooks<'a> {
87
    map: HashMap<&'a str, Vec<Hook<'a>>>,
88
}
89
90
impl Default for TemplateHooks<'_> {
91
0
    fn default() -> Self {
92
0
        Self::new()
93
0
    }
94
}
95
96
impl<'a> TemplateHooks<'a> {
97
65
    pub fn new() -> Self {
98
65
        Self { map: HashMap::new() }
99
65
    }
100
101
29
    pub fn hook(&mut self, name: &'a str, hook: impl Into<Hook<'a>>) -> &mut Self {
102
29
        let entry = self.map.entry(name).or_default();
103
29
        entry.push(hook.into());
104
29
        self
105
29
    }
106
107
59
    pub fn get_fragments(&self, name: &str) -> impl Iterator<Item = &Fragment> {
108
59
        self.map.get(name).map(|v| 
v.iter()16
).unwrap_or([].iter()).filter_map(|v|
match v22
{
109
22
            Hook::Fragment(v) => Some(v),
110
0
            Hook::Function(_) => None,
111
59
        
}22
)
112
59
    }
113
114
24
    pub fn get_functions(&self, name: &str) -> impl Iterator<Item = &str> {
115
24
        self.map.get(name).map(|v| 
v.iter()7
).unwrap_or([].iter()).filter_map(|v|
match v7
{
116
0
            Hook::Fragment(_) => None,
117
7
            Hook::Function(v) => Some(*v),
118
24
        
}7
)
119
24
    }
120
}